package work.services;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

public class AccessLogParser {

	private Map<String,Integer> countServiceUrlMap = new HashMap<String, Integer>();

	public static void main(String[] args) {

		try {
//			String[] fileLocations = new String[]{
//					"/home/gmarcone/Carpeta sin título/4/services_access_log.2014-12-08.txt.1",
//					"/home/gmarcone/Carpeta sin título/3/services_access_log.2014-12-08.txt.1"};
			new AccessLogParser().processFiles(args);
		} catch (Exception e) {
			e.printStackTrace(System.out);
		}
	}

	private void processFiles(String[] fileLocations) throws IOException {

		for (String fileLocation : fileLocations) {
			processFile(fileLocation);
		}

		dataToInfo();
	}

	private void dataToInfo() {
		System.out.println();
		for (Entry<String, Integer> entry: countServiceUrlMap.entrySet()) {
			System.out.println(entry.getValue() + "\t" + entry.getKey());
		}
	}

	private void processFile(String fileLocation) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(fileLocation));

		int lineCount = 0;
		try {
			String line;
			while ((line = br.readLine()) != null) {
				AccessLogLine logLine = createLogLine(line);
				if (logLine != null) {
					addStat(logLine);
				}
				lineCount++;

				if (lineCount % 10000 == 0) {
					System.out.println(lineCount);
				}
			}
		} finally {
			br.close();
		}
	}


	private void addStat(AccessLogLine accessLogLine) {
		String key = accessLogLine.getUrl();

		if (countServiceUrlMap.containsKey(key)) {
			countServiceUrlMap.put(key, countServiceUrlMap.get(key) + 1);
		} else {
			countServiceUrlMap.put(key, 1);
		}
	}


	private static final SimpleDateFormat sdf = new SimpleDateFormat("[dd/MMM/yyyy:HH:mm:ss",Locale.ENGLISH);
	private AccessLogLine createLogLine(String logLine) {
		try {
			String[] tokens = logLine.split(" ");

			String ipAddress = tokens[0];
			Date time;
			try {
				time = sdf.parse(tokens[3]);
			} catch (ParseException e) {
				e.printStackTrace(System.out);
				time = null;
			}
			String httpMethod = tokens[5].substring(1);

			String fullPath = tokens[6];

			String url;
			String parameters;

			if (fullPath.contains("?")) {
				url = tokens[6].substring(0,tokens[6].indexOf("?"));
				parameters = tokens[6].substring(tokens[6].indexOf("?")+1);
			} else {
				url = fullPath;
				parameters = "";
			}

			String protocol = tokens[7].substring(0, tokens[7].length()-1);
			Integer status = Integer.valueOf(tokens[8]);
			Integer contentSize = Integer.valueOf(tokens[9]);

			return new AccessLogLine(ipAddress, time, httpMethod, url, parameters, protocol, status, contentSize);

		} catch (Exception e) {
			System.out.println("Can not processLine: " + logLine);
			e.printStackTrace(System.out);
			return null;
		}
	}
}
